package com.gdufe.firesafe.interceptor;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.gdufe.firesafe.annotation.AuthAccess;
import com.gdufe.firesafe.exception.RRException;
import com.gdufe.firesafe.model.entity.UserEntity;
import com.gdufe.firesafe.service.UserService;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JWTUserInterceptor implements HandlerInterceptor {
    //注意Resource是byName的注入方式
    @Resource
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){

        String token=request.getHeader("token");//从header获取token
        if(StrUtil.isBlank(token)){
            token=request.getParameter("token");//从url获取token（?token=...）
        }
        if(handler instanceof HandlerMethod){
            //获取方法上的自定义注解AuthAccess
            AuthAccess annotation=((HandlerMethod)handler).getMethodAnnotation(AuthAccess.class);
            //如果有AuthAccess这个注解就直接通过
            if(annotation!=null){
                return true;
            }
        } else {
            //如果不是映射到方法直接通过
            return true;
        }

        //执行认证
        if(StrUtil.isBlank(token)){
            throw new RRException(401,"请登录");
        }
        //获取token中的user id
        String userId;
        try {
            userId= JWT.decode(token).getAudience().get(0);//JWT解码
        }catch (JWTDecodeException e){
            throw new RRException(401,"请登录");
        }
        //根据user id查询数据库
        UserEntity user= (UserEntity) userService.getById(Integer.valueOf(userId));
        if (user==null){
            throw new RRException(401,"请登录");
        }
        //用户密码加密形成验证器
        JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try {
            jwtVerifier.verify(token);
        }catch (TokenExpiredException e){
            throw new RRException(401,"登录已过期，请重新登录");
        } catch (JWTVerificationException e){
            throw new RRException(401,"请登录");
        }
        return true;
    }
}
